#include <stdlib.h>
#include <iostream>
#include <complex>
#include <math.h>
#include <stdio.h>
#include <fstream>
#include <time.h>

/*
 * Greg Klein, 2011
 */

using namespace std;

int num_iter = 100;
int points = 1000000;
int min_iter = 0;
char * out_fname = "out.txt";

void iterate(float,float,float,float, ofstream&);
void trace(float,float,float,float,int, ofstream&);

int main(int argc, char **argv){

  char c = 0;
  while ((c = getopt (argc, argv, "o:i:p:m:")) != -1){
       switch(c){
            case 'o'://output file
                out_fname = optarg;
                break;
            case 'i':
                num_iter = atoi(optarg);
                break;
            case 'p':
                points = (int)(atof(optarg));
                break;
            case 'm':
                min_iter = atoi(optarg);
                break;
            case '?'://unknown opt, print help then quit.
                cout<<"-p is millions of points\n-i is how deep to iterate\n"
                      "-o is output file\n-m is minimum iterations\n";
                abort();
       }
  }

  ofstream out_file;
  out_file.open(out_fname);

  srand ( time(NULL) );

  for(int x = 0;x<points;x++){
     //inner loop is millions of points so that "points"
     //can store larger numbers.
     for(int y = 0; y<1000000;y++){
          float a = ((float)(rand()))/RAND_MAX;
          float b = ((float)(rand()))/RAND_MAX;

          float a2 = ((float)(rand()))/RAND_MAX;
          float b2 = ((float)(rand()))/RAND_MAX;
     
          iterate(a*4-2, b*4-2, a2*4-2, b2*4-2,out_file);
      }
  }

  out_file.close();

  return 0;
}


void iterate(float a, float b,float cr, float ci, ofstream& out){
  int count = 0;

  float oa = a;
  float ob = b; 

  complex<float> z (a,b);
  complex<float> c (cr, ci);

  while(count<num_iter && a*a+b*b< 2){
     z = pow(z,2)+c;
    
     a = z.real();
     b = z.imag();
    
     count++;
  }

  if(count!=num_iter && count>min_iter ){
     char outbound[100]="";
     sprintf(outbound, "%f %f %f %f %d\n", oa,ob,cr,ci,count);
     out<<outbound;
       //trace(oa,ob,cr,ci, count, out);
  }
}

void trace(float a, float b, float cr, float ci, int ct, ofstream& out){


  complex<float> z (a,b);
  complex<float> c (cr, ci);
  
  int count = 0;
  
  while(count<num_iter && a*a+b*b< 2){
     z = pow(z,2)+c;
        
     a = z.real();
     b = z.imag();


     char  filename[100] = "";
     
     sprintf(filename, "%f %f %f %f %d\n", a,b,cr,ci,ct);
     out<<filename;
 
     count++;
  }

}
